package LDraw.Support; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FilenameFilter; import java.util.ArrayList; import java.util.HashMap; import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array; import Builder.BuilderConfigurationManager; import Connectivity.Axle; import Connectivity.Ball; import Connectivity.BoundingAABB; import Connectivity.CollisionBox; import Connectivity.Connectivity; import Connectivity.Connectivity.TYPE; import Connectivity.Custom2dFieldGenerator; import Connectivity.Fixed; import Connectivity.Gear; import Connectivity.Hinge; import Connectivity.Hole; import Connectivity.Rail; import Connectivity.Slider; import Connectivity.Stud; import ConnectivityEditor.Window.CollisionBoxGenerator; public class ConnectivityLibrary { public static void main(String args[]) { ConnectivityLibrary lib = ConnectivityLibrary.getInstance(); ArrayList<String> testList = new ArrayList<String>(); testList.add("4162p0u"); for (String partName : testList) { lib.getConnectivity(partName + ".dat", false, true); } } public final static String ConnectivityFilesPath = BuilderConfigurationManager.getDefaultDataDirectoryPath() + "Connectivity" + File.separator; HashMap<String, ArrayList<Connectivity>> connectivityCache; HashMap<String, ArrayList<CollisionBox>> collisionBoxCache; HashMap<String, ArrayList<BoundingAABB>> boundingAABBCache; private static ConnectivityLibrary _instance = null; private ConnectivityLibrary() { connectivityCache = new HashMap<String, ArrayList<Connectivity>>(); collisionBoxCache = new HashMap<String, ArrayList<CollisionBox>>(); boundingAABBCache = new HashMap<String, ArrayList<BoundingAABB>>(); // loadAllConnectivity(); } public synchronized static ConnectivityLibrary getInstance() { if (_instance == null) _instance = new ConnectivityLibrary(); return _instance; } public boolean hasConnectivity(String partName) { String partNameWithoutExtension = LDrawUtilities .excludeExtensionFromPartName(partName); if (connectivityCache.containsKey(partNameWithoutExtension)) return true; File cache = new File(ConnectivityFilesPath + LDrawUtilities.excludeExtensionFromPartName(partName) + ".conn"); if (cache.exists()) return true; return false; } public HashMap<String, ArrayList<Connectivity>> getConnectivity() { return connectivityCache; } public ArrayList<Connectivity> getConnectivity(String partName) { return getConnectivity(partName, true, true); } public ArrayList<Connectivity> getConnectivity(String partName, boolean useConnExtractor, boolean useCache) { String partNameWithoutExtension = LDrawUtilities .excludeExtensionFromPartName(partName); String representPartNameWithoutExtension = LDrawUtilities .excludeExtensionFromPartName(PartCache.getInstance() .getRepresentPartName(partName)); ArrayList<Connectivity> original = null; ArrayList<Connectivity> copy = new ArrayList<Connectivity>(); if (useCache == false) { connectivityCache.remove(partNameWithoutExtension); collisionBoxCache.remove(partNameWithoutExtension); boundingAABBCache.remove(partNameWithoutExtension); } if (connectivityCache.containsKey(partNameWithoutExtension)) original = connectivityCache.get(partNameWithoutExtension); if (original == null) if (loadConnectivity(partNameWithoutExtension, partNameWithoutExtension)) original = connectivityCache.get(partNameWithoutExtension); if (original == null && representPartNameWithoutExtension .equals(partNameWithoutExtension) == false) { if (loadConnectivity(representPartNameWithoutExtension, representPartNameWithoutExtension)) original = connectivityCache .get(representPartNameWithoutExtension); } // test if (original == null) { // only apply for part name start with numbers. String candidatePartName = LDrawUtilities .excludePatternWithoutExtension(partNameWithoutExtension); if (candidatePartName != null && candidatePartName != "") { if (loadConnectivity(candidatePartName, partNameWithoutExtension)) { original = connectivityCache.get(partNameWithoutExtension); } } } if (useConnExtractor == true && original == null && collisionBoxCache.containsKey(partName) == false) { long t = System.currentTimeMillis(); Custom2dFieldGenerator.getInstance().getStudInfo(partName); Custom2dFieldGenerator.getInstance().getHoleInfo(partName); if (loadConnectivity(partNameWithoutExtension, partNameWithoutExtension)) original = connectivityCache.get(partNameWithoutExtension); else connectivityCache.put(partNameWithoutExtension, new ArrayList<Connectivity>()); Custom2dFieldGenerator.getInstance().deleteConnFile(partName); System.out.println("Generating Conn Info for " + partName + " requires " + (System.currentTimeMillis() - t) + "ms"); } if (useConnExtractor && (collisionBoxCache.containsKey(partNameWithoutExtension) == false || collisionBoxCache .get(partNameWithoutExtension).size() == 0)) collisionBoxCache.put( partNameWithoutExtension, CollisionBoxGenerator.getInstance().generateCollisionBox( partName)); if (original == null) return new ArrayList<Connectivity>(); for (Connectivity conn : original) { Connectivity conn_copy = null; try { if (Stud.class.isInstance(conn)) { conn_copy = (Stud) ((Stud) conn).clone(); } else if (Hole.class.isInstance(conn)) { conn_copy = (Hole) ((Hole) conn).clone(); } else { conn_copy = (Connectivity) conn.clone(); } copy.add(conn_copy); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return copy; } public ArrayList<CollisionBox> getCollisionBox(String key) { return getCollisionBox(key, true); } public ArrayList<CollisionBox> getCollisionBox(String partName, boolean useCache) { ArrayList<CollisionBox> retList = new ArrayList<CollisionBox>(); String partNameWithoutExtension = LDrawUtilities .excludeExtensionFromPartName(partName); if (useCache == false) getConnectivity(partName, true, false); if (collisionBoxCache.containsKey(partNameWithoutExtension)) for (CollisionBox cBox : collisionBoxCache .get(partNameWithoutExtension)) { try { retList.add((CollisionBox) cBox.clone()); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return retList; } public ArrayList<BoundingAABB> getBoundingAABB(String key) { String partNameWithoutExtension = LDrawUtilities .excludeExtensionFromPartName(key); if (boundingAABBCache.containsKey(partNameWithoutExtension)) return boundingAABBCache.get(partNameWithoutExtension); return null; } private boolean loadConnectivity(String partName, String originalPartName) { File cache = new File(ConnectivityFilesPath + LDrawUtilities.excludeExtensionFromPartName(partName) + ".conn"); if (!cache.exists()) { return false; } BufferedReader reader = null; String line = null, lines[]; String partNameWithoutExtension = LDrawUtilities .excludeExtensionFromPartName(originalPartName); ArrayList<Connectivity> connectivities; ArrayList<CollisionBox> collisionBoxes; ArrayList<BoundingAABB> boundingAABBs; Connectivity connectivity = null; try { reader = new BufferedReader(new FileReader(cache)); TYPE[] types = TYPE.values(); while ((line = reader.readLine()) != null) { if ("".equals(line)) continue; lines = line.split(" "); switch (types[Integer.parseInt(lines[0])]) { case Comment: continue; case Import: return loadConnectivity(lines[1], originalPartName); case Axle: connectivity = new Axle(); break; case Ball: connectivity = new Ball(); break; case Fixed: connectivity = new Fixed(); break; case Gear: connectivity = new Gear(); break; case Hinge: connectivity = new Hinge(); break; case Hole: connectivity = new Hole(); break; case Rail: connectivity = new Rail(); break; case Slider: connectivity = new Slider(); break; case Stud: connectivity = new Stud(); break; case CollisionBox: connectivity = new CollisionBox(); break; case BoundingAABB: connectivity = new BoundingAABB(); break; } connectivity.parseString(lines); if (connectivity instanceof CollisionBox) { collisionBoxes = collisionBoxCache .get(partNameWithoutExtension); if (collisionBoxes == null) { collisionBoxes = new ArrayList<CollisionBox>(); collisionBoxCache.put(partNameWithoutExtension, collisionBoxes); } collisionBoxes.add((CollisionBox) connectivity); } else if (connectivity instanceof BoundingAABB) { boundingAABBs = boundingAABBCache .get(partNameWithoutExtension); if (boundingAABBs == null) { boundingAABBs = new ArrayList<BoundingAABB>(); boundingAABBCache.put(partNameWithoutExtension, boundingAABBs); } boundingAABBs.add((BoundingAABB) connectivity); } else { connectivities = connectivityCache .get(partNameWithoutExtension); if (connectivities == null) { connectivities = new ArrayList<Connectivity>(); connectivityCache.put(partNameWithoutExtension, connectivities); } connectivities.add(connectivity); } } reader.close(); } catch (Exception e) { System.out.println(partName); System.out.println(line); e.printStackTrace(); } return true; } public ArrayList<String> getAllConnectiblePartIdList() { ArrayList<String> retList = new ArrayList<String>(); File connectivities = new File("./Resource/connectivity"); File[] lists = connectivities.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.endsWith("conn"); } }); for (File file : lists) { retList.add(LDrawUtilities.excludeExtensionFromPartName(file .getName())); } return retList; } public void loadAllConnectivity() { for (String partName : getAllConnectiblePartIdList()) { getConnectivity(partName + ".dat", false, true); } } }